/*****************************************************************************//*!
* file  : systask.c
* creat : apleilx
* data  : 2017/11/05
*******************************************************************************/

#include "os_obj.h"
#define _SYSTASK_MODULE_
#include "sys_task.h"
#undef _SYSTASK_MODULE_
#include "pincfg.h"
#include "sys_init.h"
#include "com_obj.h"
#include "common.h"
#include "bsp_hal.h"
#include "rtc85163.h"
#include "usb_file.h"
#include "mbapp.h"
#include "flash_task.h"

void sys_led_ctr(void);
void sys_crc_handle(char pos);

void modbus_task(ULONG thread_input);
void print_hy01(void);
void rtc_time_manager(void);
void sys_input_handle(void);
void hist_ctr(void);
void in_sim(void);

/*****************************************************************************
*
* @brief   system task.
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void task_system(ULONG thread_input)
{
	uint32_t us_tick_s, us_tick_end;

	(void)thread_input;

	sys_init();

	sys_cfg_load();

	while (1)
	{
		bsp_dwt_check();

		us_tick_s = app_tick_us_get();

		sys_st.u_tick = app_tick_get();

		pulse_create(&sys_st.pulse, sys_st.u_tick);

		rtc_time_manager();

		modbus_task(thread_input);

		sys_st.sig_time = time_to_sig(&sys_st.rtc_time);

		if (sys_st.powerup_time_cnt >= 60)
		{
			print_hy01();
			hist_ctr();
		}

		if (sys_st.pulse.bPulse_100ms)
			sys_st.powerup_time_cnt++;

		sys_led_ctr();

#ifdef DEBUG
		in_sim();
#else
		sys_input_handle();
#endif

		us_tick_end = app_tick_us_get();

		sys_st.exe_time_us = us_tick_end - us_tick_s;

		if (sys_st.exe_time_us_max < sys_st.exe_time_us)
		{
			sys_st.exe_time_us_max = sys_st.exe_time_us;
		}

		//存储配置参数
		if (sys_st.sys_save_req)
		{
			sys_cfg_save();
			sys_st.sys_save_req = 0;
		}

		osDelay(ms_ticks(10));
	}
}

/*****************************************************************************
*
* @brief   led control.
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void sys_led_ctr(void)
{
	if (sys_st.led_req.flash_clr_st)
	{
		if (sys_st.pulse.bPulse_500ms)
		{
			o_led_ext.tog();
		}
	}
	else if (usb_opt.opt_st == USER_INIT)
	{
		sys_st.led_req.ext_led_flash_delay = 0;

		if (mb_m.success_keep_cnt == 0)
		{
			o_led_ext.en();
		}
		else
		{
			o_led_ext.dis();
		}
	}
	else if (usb_opt.opt_st < USER_USB_RUN_FILE_HANDLE)
	{
		if (sys_st.pulse.bPulse_500ms)
		{
			o_led_ext.tog();
		}
	}
	else
	{
		if (sys_st.pulse.bPulse_500ms && sys_st.led_req.ext_led_flash_delay < 127)
			sys_st.led_req.ext_led_flash_delay++;

		if (sys_st.led_req.ext_led_flash_delay <= 5)
		{
			if (sys_st.pulse.bPulse_500ms)
			{
				o_led_ext.tog();
			}
		}
		else
		{
			o_led_ext.en();

			if (sys_st.led_req.usb_ran_save)
			{
				o_led_ext.tog();
			}
		}
	}

	//
	if (sys_st.pulse.bWave_500ms)
	{
		o_led_run.en();
	}
	else
	{
		o_led_run.dis();
	}

	if (mb_m.idle_time_cnt > 2000)
	{
		o_led_com.dis();
	}
	else if (mb_m.success_keep_cnt > 1)
	{
		o_led_com.en();
	}
	else if (mb_m.run_st.bits.port_st)
	{
		if (sys_st.pulse.bWave_500ms)
			o_led_com.en();
		else
			o_led_com.dis();
	}
	else
	{
		o_led_com.dis();
	}


	if (usb_opt.opt_st == USER_INIT)
	{
		o_led_usb.dis();
	}
	else if (usb_opt.opt_st < USER_USB_RUN_FILE_HANDLE)
	{
		if (sys_st.pulse.bPulse_250ms)
		{
			o_led_usb.tog();
		}
	}
	else
	{
		o_led_usb.en();
		if (sys_st.led_req.usb_ran_save)
		{
			o_led_usb.tog();
		}
	}

	sys_st.led_req.usb_ran_save = 0;
}

/*****************************************************************************
*
* @brief   task switch hook.
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void task_sw_hook(char pos)
{

}


/*****************************************************************************
* @brief   task switch hook.
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void sys_pre_init(char pos)
{
	RCC_ClockType clk;
	RCC_GetClocksFreq(&clk);

	sys_st.dbg.clk_adc = clk.ADCCLK_Freq;
	sys_st.dbg.clk_ahb = clk.AHBCLK_Freq;
	sys_st.dbg.clk_apb1 = clk.APB1CLK_Freq;
	sys_st.dbg.clk_apb2 = clk.APB2CLK_Freq;
	sys_st.dbg.clk_sys = clk.SYSCLK_Freq;
}
OBJ_INIT_APP_EXPORT(sys_pre_init);

/*****************************************************************************
* @brief   task switch hook.
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void rtc_time_manager(void)
{
	uint16_t local_rtc_on_req;
	TIME_Type rtc_update;

	local_rtc_on_req = 0;

	if (sys_st.local_rtc_on_req_old != local_rtc_on_req)
	{
		if (local_rtc_on_req == 1)
		{
			rtc_update.year = 2020;
			rtc_update.mon = 8;
			rtc_update.day = 15;
			rtc_update.hour = 12;
			rtc_update.min = 30;
			rtc_update.sec = 0;

			RtcStop();
			RtcSetTime(&rtc_update);
			RtcStart();

			sys_st.b_rtc_on_back_req = 1;
		}
	}

#if LOCAL_RTC_SIM > 0
	if (!sys_st.dbg.rtc_sim_init)
	{
		if (sys_st.powerup_time_cnt > 30)
		{
			time_sig_to_time(sys_st.hist_opt.time_hist_powerup, &sys_st.rtc_time_local);
			sys_st.dbg.rtc_sim_init = 1;
		}
	}
	else
	{
		if (sys_st.pulse.bPulse_1s)
			rtc_time_run_min(&sys_st.rtc_time_local, 1);
	}
#else
	if (sys_st.pulse.bPulse_1s)
	{
		TIME_Type rtc_update;

		RtcGetTime(&sys_st.rtc_time_local);

		if ((sys_st.rtc_time_local.mon) == 0 || (sys_st.rtc_time_local.day == 0))
		{
			sys_st.local_rtc_err_cnt++;
			if (sys_st.local_rtc_err_cnt > 3)
			{
				time_sig_to_time(sys_st.hist_opt.time_hist_powerup, &rtc_update);

				RtcStop();
				RtcSetTime(&rtc_update);
				RtcStart();
			}
		}
		else
		{
			sys_st.local_rtc_err_cnt = 0;
		}
	}

#endif  

	sys_st.local_rtc_on_req_old = local_rtc_on_req;
}

/*****************************************************************************
* @brief   task switch hook.
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void sys_crc_handle(char pos)
{
	CRC->CTRL = CRC_CTRL_RST;

	cpu_data_sync();

	CRC->DT = 11111111;
	CRC->DT = 22222222;
	CRC->DT = 33333333;
	CRC->DT = 44444444;
	CRC->DT = 55555555;

	cpu_data_sync();

	sys_st.dbg.crc_val = CRC->DT;

	CRC->CTRL = CRC_CTRL_RST;
}

/*****************************************************************************
* @brief   sys_input_handle.
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void sys_input_handle(void)
{
	uint16_t inr = 0;
	
#ifndef DEBUG
	intx_alloc();

	if (sys_st.powerup_time_cnt == 100)
	{
		intx_enable();
		//关闭 SWD
		//GPIO_PinsRemapConfig(AFIO_MAP7_SWJTAG_0100, ENABLE);

		intx_disable();
	}
#endif

	// 按键
	io_flt(&sys_st.key, 1, !in_key.in_st());
	sys_st.key_info.sig_new = sys_st.key.st;
	io_signal_info_handle(&sys_st.key_info, 1);

	// 输入信号
	if(!in_sw1.in_st())
		inr |= 1UL << 0;
	if(!in_sw2.in_st())
		inr |= 1UL << 1;
	if(!in_sw3.in_st())
		inr |= 1UL << 2;
	if(!in_sw4.in_st())
		inr |= 1UL << 3;
	
	if(!in_sw11.in_st())
		inr |= 1UL << 8;
	if(!in_sw12.in_st())
		inr |= 1UL << 9;
	if(!in_sw13.in_st())
		inr |= 1UL << 10;
	if(!in_sw14.in_st())
		inr |= 1UL << 11;
	if(!in_sw15.in_st())
		inr |= 1UL << 12;
	if(!in_sw16.in_st())
		inr |= 1UL << 13;
	
	io16_simp_flt(&sys_st.in, 10, inr);
}


void in_sim(void)
{
	
}
